
module OPLL(
  input  wire       clk,
  input  wire       clken,
  input  wire       rst_n,
  input  wire [7:0] D,
  input  wire       A,
  input  wire       WE_n,
  output wire [9:0] MO,
  output wire [9:0] RO
);

reg       opllwr;
reg [7:0] opllptr;
reg [7:0] oplldat;
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        opllwr  <= #1 1'b0;
        opllptr <= #1 8'b0;
        oplldat <= #1 8'b0;
    end
    else if(!clken)begin
        opllwr  <= #1 opllwr;
        opllptr <= #1 opllptr;
        oplldat <= #1 oplldat;
    end
    else if(!WE_n && !A)begin
        opllwr  <= #1 1'b0;
        opllptr <= #1 D;
        oplldat <= #1 oplldat;
    end 
    else if(!WE_n && A)begin
        opllwr  <= #1 1'b1;
        opllptr <= #1 opllptr;
        oplldat <= #1 D;
    end 
end

wire[4:0] slot0;
wire[1:0] stage0;
SlotCounter U_S0(
    .clk    ( clk    ),
    .rst_n  ( rst_n  ),
    .clken  ( clken  ),
    .slot   ( slot0  ),
    .stage  ( stage0 )
);

wire[4:0] slot2;
wire[1:0] stage2;
SlotCounter U_S2(
    .clk    ( clk    ),
    .rst_n  ( rst_n  ),
    .clken  ( clken  ),
    .slot   ( slot2  ),
    .stage  ( stage2 )
);

wire[4:0] slot5;
wire[1:0] stage5;
SlotCounter U_S5(
    .clk    ( clk    ),
    .rst_n  ( rst_n  ),
    .clken  ( clken  ),
    .slot   ( slot5  ),
    .stage  ( stage5 )
);

wire[4:0] slot8;
wire[1:0] stage8;
SlotCounter U_S8(
    .clk    ( clk    ),
    .rst_n  ( rst_n  ),
    .clken  ( clken  ),
    .slot   ( slot8  ),
    .stage  ( stage8 )
);

wire       rhythm;
wire       am;
wire       pm;
wire       wf;
wire [3:0] ml;
wire [6:0] tl;
wire [2:0] fb;
wire [3:0] ar;
wire [3:0] dr;
wire [3:0] sl;
wire [3:0] rr;
wire [2:0] blk;
wire [8:0] fnum;
wire       key;
wire [3:0] rks;

Controller U_Controller(
    .clk(clk),
    .rst_n(rst_n),
    .clken(clken),
    .slot(slot0),
    .stage(stage0),
    .WE_n(WE_n),
    .A(A),
    .D(D),
    .am(am),
    .pm(pm),
    .wf(wf),
    .ml(ml),
    .tl(tl),
    .fb(fb),
    .ar(ar),
    .dr(dr),
    .sl(sl),
    .rr(rr),
    .blk(blk),
    .fnum(fnum),
    .rks(rks),
    .key(key),
    .rhythm(rhythm)
);

wire [6:0] egout;
EG U_EG(
    .clk(clk),
    .rst_n(rst_n),
    .clken(clken),
    .slot(slot2),
    .stage(stage2),
    .rhythm(rhythm),
    .am(am),
    .tl(tl),
    .ar(ar),
    .dr(dr),
    .sl(sl),
    .rr(rr),
    .rks(rks),
    .key(key),
    .egout(egout)
);

wire       noise;
wire [8:0] pgout;
PG U_PG(
    .clk    ( clk    ),
    .rst_n  ( rst_n  ),
    .clken  ( clken  ),
    .slot   ( slot2  ),
    .stage  ( stage2 ),
    .rhythm ( rhythm ),
    .pm     ( pm     ),
    .ml     ( ml     ),
    .blk    ( blk    ),
    .fnum   ( fnum   ),
    .key    ( key    ),
    .noise  ( noise  ),
    .pgout  ( pgout  )
);

wire [7:0] opout;
wire [3:0] faddr;
wire [9:0] fdata;
Operator U_OPerator(
    .clk(clk),
    .rst_n(rst_n),
    .clken(clken),
    .slot(slot0),
    .stage(stage0),
    .rhythm(rhythm),
    .WF(wf),
    .FB(fb),
    .noise(noise),
    .pgout(pgout),
    .egout(egout),
    .faddr(faddr),
    .fdata(fdata),
    .opout(opout)
);

wire [4:0] maddr;
wire [9:0] mdata;
OutputGenerator U_OutputGenerator(
    .clk(clk),
    .rst_n(rst_n),
    .clken(clken),
    .slot(slot8),
    .stage(stage8),
    .rhythm(rhythm),
    .opout(opout),
    .faddr(faddr),
    .fdata(fdata),
    .maddr(maddr),
    .mdata(mdata)
);

TemporalMixer U_TemporalMixer(
    .clk(clk),
    .rst_n(rst_n),
    .clken(clken),
    .slot(slot0),
    .stage(stage0),
    .rhythm(rhythm),
    .maddr(maddr),
    .mdata(mdata),
    .mo(MO),
    .ro(RO)
);


endmodule
